package com.hhj.demo.aopdemo;


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * Created by KING on 2018/7/18.
 */
@Component  //加入IOC容器
@Aspect  // 指定当前类为切面类
public class MyAop {


    // 指定切入点表达式： 拦截哪些方法； 即为哪些类生成代理对象
    //解释@Pointcut("execution(* cn.itcast.e_aop_anno.*.*(..))")
    /*
    整个表达式可以分为五个部分：

            1、execution(): 表达式主体。

            2、第一个*号：表示返回类型， *号表示所有的类型。

            3、包名：表示需要拦截的包名，后面的两个句点表示当前包和当前包的所有子包，com.sample.service.impl包、子孙包下所有类的方法。

            4、第二个*号：表示类名，*号表示所有的类。

            5、*(..):最后这个星号表示方法名，*号表示所有的方法，后面括弧里面表示方法的参数，两个句点表示任何参数*/
    //@Pointcut("execution(*    切入点表达式固定写法, cn.itcast.e_aop_anno表示包.类名(可以用*表示包下所有的类).方法名(可以用*表示类下所有的方法)(..)表示参数可以用..
    @Pointcut("execution(* com.hhj.demo.aopdemo.*.*(..))")
    public void pointCuts() {
        System.out.println("pointCuts...");
    }

    //@Before("execution(* cn.itcast.e_aop_anno.*.*(..))")每个方法需要写相同的引用，所以将相同的部分抽取到一个空的方法中pointCut_(),

    // 前置通知 : 在执行目标方法之前执行
    @Before(value ="pointCuts()")
    public void begin() {
        System.out.println("开始事务/异常");
    }

    // 后置/最终通知：在执行目标方法之后执行  【无论是否出现异常最终都会执行】
    @After(value ="pointCuts()")
    public void after() {
        System.out.println("提交事务/关闭");
    }

    // 返回后通知： 在调用目标方法结束后执行 【出现异常不执行】
    @AfterReturning("pointCuts()")
    public void afterReturning() {
        System.out.println("afterReturning()");
    }

    // 异常通知： 当目标方法执行异常时候执行此关注点代码
    @AfterThrowing("pointCuts()")
    public void afterThrowing() {
        System.out.println("afterThrowing()");
    }

    // 环绕通知：环绕目标方式执行
    @Around("pointCuts()")
    public void around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("环绕前....");
        pjp.proceed();  // 执行目标方法
        System.out.println("环绕后....");
    }


}
